﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QuantitativeInvestment.Bean;
using QuantitativeInvestment.Tools;
using System.Data;
using System.Reflection;
namespace QuantitativeInvestment.Container
{
    class Container
    {
        public Dictionary<string, Parameter> paraList;
        public Dictionary<string, Stock> stocks;
        public List<string> tradingDates;
        public DataModel dataModel;
        public List<Model.Model> modelList;
        public List<StockPool.StockPool> poolList;
        public List<CharacterAnalyzer.CharacterAnalyzer> analyserList;
        public string name;
        //进度条检测
        public double  progressValue;

        //容器是否测试模式
        public bool isTestModel = false;

        public Container()
        {
            this.paraList = new Dictionary<string, Parameter>();
            Parameter p = new Parameter("开始时间", "20060104");
            this.paraList.Add(p.name, p);

            p = new Parameter("结束时间", "20101231");
            this.paraList.Add(p.name, p);
           

            p = new Parameter("基准指数", "沪深300");
            p.enumList.Add("中证100");
            p.enumList.Add("中证200");
            p.enumList.Add("中证500");
            p.enumList.Add("中证700");
            p.enumList.Add("中证800");
            p.enumList.Add("上证综指");
            p.type = "enum";
            this.paraList.Add(p.name, p);

            p = new Parameter("买入价格", "收盘价");
            p.type = "enum";
            this.paraList.Add(p.name, p);

            p = new Parameter("卖出价格", "收盘价");
            p.type = "enum";
            this.paraList.Add(p.name, p);

            p = new Parameter("交易成本", "0.001");
            this.paraList.Add(p.name, p);

            this.stocks = new Dictionary<string, Stock>();

            this.dataModel = new DataModel();

            this.poolList = new List<StockPool.StockPool>();


            this.modelList = new List<Model.Model>();
        }
        /// <summary>
        /// 按照特定条件跑历史记录
        /// </summary>
        public virtual void run()
        {

        }

        /// <summary>
        /// 在测试模式之下,参数组合
        /// </summary>
        public virtual void testModeRun()
        {

        }
        /// <summary>
        /// 取得模型最新的投资组合列表
        /// </summary>
        public virtual void lastestPortfolios()
        {
          
        }

        public void updateStocks(List<TradingStock> tradingStocks)
        {
            string startDate = this.paraList["开始时间"].value.ToString();
            string endDate = this.paraList["结束时间"].value.ToString();
            foreach(TradingStock tradingStock in tradingStocks)
            {
                //如果股票不在数据库就创建股票，并且加入因子
                if (!this.stocks.ContainsKey(tradingStock.code))
                {
                    
                    Stock stock = new Stock(tradingStock.code,tradingStock.name);
                    stock.tradingDateList = this.dataModel.getStockTradingDates(tradingStock.code,"19891231",endDate);
                    if (stock.tradingDateList.Count > 2)
                    {
                        stock.startDate = this.dataModel.getNearestStockTradingDate(stock.code,startDate);
                        stock.endDate = stock.tradingDateList[stock.tradingDateList.Count - 1];
                    }
                    //加入因子值
                    foreach (Model.Model model in this.modelList)
                    {
                        foreach (Factor.Factor factor in model.factorList)
                        {
                            if (factor.type == "private")
                                factor.addFactorValue(stock);
         
                        }
                    }
                    this.stocks.Add(tradingStock.code, stock);
                }
            }
        }

        //收益统计
        public virtual void caculateStatistics()
        {
            

        }



        public static Container createContainerByName(String name)
        {
            Container container = null;
            DataSet ds = new DataSet();
            ds.ReadXml(System.Windows.Forms.Application.StartupPath + "/Config" + "/Containers.xml");
            DataRow[] rows = ds.Tables["container"].Select("name='" + name + "'");
            if (rows.Length > 0)
            {
                Assembly a = Assembly.GetExecutingAssembly();
                container = (Container)a.CreateInstance(rows[0]["objectName"].ToString());
            }

            return container;
        }

        //设定买入和卖出价格
        public  void setBuyPrice(TradingStock tradingStock)
        {

            //  tradingStock.buyPrice = this.dataModel.getAdjustedStockClosePrice(tradingStock.code, tradingStock.buyDate);
            int buyPosition = this.stocks[tradingStock.code].tradingDateList.IndexOf(tradingStock.buyDate);
            int initialStartPosition = this.stocks[tradingStock.code].tradingDateList.IndexOf(this.stocks[tradingStock.code].startDate);
            if (buyPosition == -1)
            {
                tradingStock.buyPrice = this.dataModel.getAdjustedStockClosePrice(tradingStock.code, tradingStock.buyDate);
            }
            else
            {
                tradingStock.buyPrice = this.stocks[tradingStock.code].factors["价格收盘价"][buyPosition - initialStartPosition];
            }
         
        }

        //设定买入和卖出价格
        public void setSellPrice(TradingStock tradingStock)
        {
          //  tradingStock.sellPrice = this.dataModel.getAdjustedStockClosePrice(tradingStock.code, tradingStock.sellDate);
            int sellPosition = this.stocks[tradingStock.code].tradingDateList.IndexOf(tradingStock.sellDate);
            int initialStartPosition = this.stocks[tradingStock.code].tradingDateList.IndexOf(this.stocks[tradingStock.code].startDate);
 
            if (sellPosition == -1)
            {
                tradingStock.sellPrice = this.dataModel.getAdjustedStockClosePrice(tradingStock.code, tradingStock.sellDate);
            }
            else
            {
                tradingStock.sellPrice = this.stocks[tradingStock.code].factors["价格收盘价"][sellPosition - initialStartPosition];
            }
          
        
        }
    }
}
